Tweak the meaning of HTTP timeouts
authorAlex Crichton <alex@alexcrichton.com>
Wed, 29 Apr 2015 18:58:13 +0000 (11:58 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 30 Apr 2015 01:46:24 +0000 (18:46 -0700)
Previously a timeout was set via libcurl's blanket timeout option, which is a
timeout for the entire request. This isn't always what we want, however, as
cargo is used on quite a variety of networks. Instead what we really want is
timing out data being received, so instead of a blanket timeout we set two
different timeouts:

* The connect timeout is now configured (time it takes to connect the socket)
* A "low speed" timeout is now also set. This means that if Cargo doesn't
  receive 10 bytes of data in the specified tiemout period that the entire
  transfer will be timed out.

Closes #1560

Cargo.lock
src/cargo/ops/registry.rs

index d8b5af4dcb12a1b981b66af9edf7a5b2c672fb9a..a7819cdd8c289eb334762c803092aea67b319b44 100644 (file)
@@ -148,7 +148,7 @@ version = "0.2.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libssh2-sys 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libssh2-sys 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -164,7 +164,7 @@ dependencies = [
 
 [[package]]
 name = "libssh2-sys"
-version = "0.1.19"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
index bae8643c0e4c2a6d6ea4b0b4c56c31054ed0aa9b..7bd22b3606ba7f7b5fc95bea5b3b4ddfd00fc7b5 100644 (file)
@@ -166,13 +166,21 @@ pub fn registry(config: &Config,
 
 /// Create a new HTTP handle with appropriate global configuration for cargo.
 pub fn http_handle(config: &Config) -> CargoResult<http::Handle> {
-    let handle = http::handle().timeout(60_000);
+    // The timeout option for libcurl by default times out the entire transfer,
+    // but we probably don't want this. Instead we only set timeouts for the
+    // connect phase as well as a "low speed" timeout so if we don't receive
+    // many bytes in a large-ish period of time then we time out.
+    let handle = http::handle().timeout(0)
+                               .connect_timeout(30_000 /* milliseconds */)
+                               .low_speed_limit(10 /* bytes per second */)
+                               .low_speed_timeout(30 /* seconds */);
     let handle = match try!(http_proxy(config)) {
         Some(proxy) => handle.proxy(proxy),
         None => handle,
     };
     let handle = match try!(http_timeout(config)) {
-        Some(timeout) => handle.timeout(timeout as usize),
+        Some(timeout) => handle.connect_timeout(timeout as usize)
+                               .low_speed_timeout((timeout as usize) / 1000),
         None => handle,
     };
     Ok(handle)